package learnjava.concur.chapter8;

import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
 * 测试ExecutorService的方法
 */
@Slf4j(topic = "P017")
public class P017 {

    public static void main(String[] args) throws Exception {

        ExecutorService pool = Executors.newFixedThreadPool(7);
        for (int i = 0; i < 10000; i++) {
            pool.execute(()->{
                int a = Integer.MAX_VALUE;
                int b = a%5;
            });
        }
        pool.shutdown();
    }

    /**
     * 1.1 submit：提交带返回值的任务
     * @param pool
     */
    static void testSubmit(ExecutorService pool){
        Future<String> future = pool.submit(() -> {  //传入一个callable接口
            log.debug("running");
            return "OK";
        });
        try {
            log.debug("{}",future.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 1.2 invokeAll：批量提交带返回值的任务，返回值的顺序和传入的顺序一样
     */
    static void testInvokeAll(ExecutorService pool) throws Exception{
        List<Future<String>> futures = pool.invokeAll(Arrays.asList(
                ()->{log.debug("1running");Thread.sleep(200);return "1";},
                ()->{log.debug("2running");Thread.sleep(100);return "2";},
                ()->{log.debug("3running");Thread.sleep(100);return "3";}
        ));

        futures.forEach(f->{
            try {
                log.debug("{}",f.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * 1.3 invokeAny：批量提交带返回值的任务，只要有一个任务执行完了，就返回那个任务的结果
     */
    static void testInvokeAny(ExecutorService pool) throws Exception{
        String res = pool.invokeAny(Arrays.asList(
                ()->{log.debug("1running");Thread.sleep(100);return "1";},
                ()->{log.debug("2running");Thread.sleep(100);return "2";},
                ()->{log.debug("3running");Thread.sleep(100);return "3";}
        ));
        try {
            log.debug("{}",res);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 1.4 shutdown: 不接收新任务，等待正在执行的和等待队列的任务完成
     */
    static void testShutdown(ExecutorService pool) throws InterruptedException {
        Future<Integer> res1 = pool.submit(()->{
            log.debug("task1 running");
            Thread.sleep(1000);
            log.debug("task1 finish");
            return 1;
        });

        Future<Integer> res2 = pool.submit(()->{
            log.debug("task2 running");
            Thread.sleep(1000);
            log.debug("task2 finish");
            return 2;
        });

        Future<Integer> res3 = pool.submit(()->{
            log.debug("task3 running");
            Thread.sleep(1000);
            log.debug("task3 finish");
            return 3;
        });



        log.debug("shutdown");
        pool.shutdown();
        pool.awaitTermination(3,TimeUnit.SECONDS); //不加的话，main不等shutdown完成
        log.debug("main other");

        //reject
        Future<Integer> res4 = pool.submit(()->{
            log.debug("task4 running");
            Thread.sleep(1000);
            log.debug("task4 finish");
            return 4;
        });
    }

    /**
     * 1.5 shutdownNow: 不接收新任务，打断正在执行的和等待队列的任务，并返回等待队列的任务
     */
    static void testShutdownNow(ExecutorService pool) throws InterruptedException {
        Future<Integer> res1 = pool.submit(()->{
            log.debug("task1 running");
            Thread.sleep(1000);
            log.debug("task1 finish");
            return 1;
        });

        Future<Integer> res2 = pool.submit(()->{
            log.debug("task2 running");
            Thread.sleep(1000);
            log.debug("task2 finish");
            return 2;
        });

        Future<Integer> res3 = pool.submit(()->{
            log.debug("task3 running");
            Thread.sleep(1000);
            log.debug("task3 finish");
            return 3;
        });



        log.debug("shutdown");
        List<Runnable> runnables = pool.shutdownNow();
        pool.awaitTermination(3,TimeUnit.SECONDS); //不加的话，main不等shutdown完成
        log.debug("main other");

        //reject
        Future<Integer> res4 = pool.submit(()->{
            log.debug("task4 running");
            Thread.sleep(1000);
            log.debug("task4 finish");
            return 4;
        });
    }


}